package com.woniu.advice;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.annotation.RequestLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.Arrays;

@Aspect
@Component
public class RequestLogAdvice {
    private static final Logger logger = LoggerFactory.getLogger("requestLog");

    @Pointcut(value = "execution(* com.woniu.service.impl.*.*(..))")
    private void logPointCut() {
    }

    @Before("logPointCut()")
    public void doBefore(JoinPoint joinPoint) throws Exception {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RequestLog annotation = method.getAnnotation(RequestLog.class);
        if (annotation == null) {
            return;
        }
        String methodName = method.getDeclaringClass().getSimpleName() + "#" + method.getName();
        Object[] args = joinPoint.getArgs();
        Arrays.stream(args).forEach(e -> {
            ObjectMapper objectMapper = new ObjectMapper();
            String str = null;
            try {
                str = objectMapper.writeValueAsString(e);
            } catch (JsonProcessingException jsonProcessingException) {
                jsonProcessingException.printStackTrace();
            }
            logger.info("method={}; params={}", methodName, str);
        });

    }

    @AfterReturning(value = "logPointCut()", returning = "result")
    public void afterReturn(JoinPoint joinPoint, Object result) throws Exception {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        RequestLog annotation = method.getAnnotation(RequestLog.class);
        if (annotation == null) {
            return;
        }
        String methodName = method.getDeclaringClass().getSimpleName() + "#" + method.getName();
        ObjectMapper objectMapper = new ObjectMapper();
        String str = objectMapper.writeValueAsString(result);
        logger.info("method={}; response={}", methodName, str);
    }

}
